package cc.xuzhi.muggle.devtools.service;

import cc.xuzhi.muggle.common.exception.ErrorCode;
import cc.xuzhi.muggle.common.exception.ServiceException;
import cc.xuzhi.muggle.common.util.DataUtils;
import cc.xuzhi.muggle.devtools.mapper.DevtoolsConfigMapper;
import cc.xuzhi.muggle.devtools.model.DevtoolsConfig;
import cc.xuzhi.muggle.devtools.model.dto.ConfigSaveDTO;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import lombok.val;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * 系统配置
 *
 * @author xuzhi
 * @date 2022-05-26 21:20:53
 */
@Slf4j
@Service
public class DevtoolsConfigService extends ServiceImpl<DevtoolsConfigMapper, DevtoolsConfig> {

    @Autowired
    private TableService tableService;

    /**
     * 新增配置
     *
     * @return
     */
    public boolean saveSystemConfig(ConfigSaveDTO params) {
        // 校验表是否存在,如果表不存在则创建表
        if(!tableService.checkTableExist("devtools_config")) {
            this.baseMapper.initDevtoolsConfigTable();
        }

        DevtoolsConfig config = this.findByCode(params.getCode());
        if(config == null) {
            config = DevtoolsConfig.init(params.getCode());
        }

        config.setConfig(JSON.toJSONString(params.getConfig()));

        // 对配置进行存储
        return super.saveOrUpdate(config);
    }

    /**
     * 根据Code获取配置信息
     * @param code
     * @return
     */
    public DevtoolsConfig findByCode(String code) {
        val query = Wrappers.lambdaQuery(DevtoolsConfig.class)
                .eq(DevtoolsConfig::getCode, code);
        return this.getOne(query);
    }

    /**
     * 加载配置文件
     * @param config
     * @return
     */
    public Object loadConfig(DevtoolsConfig config) {
        // 根据配置文件信息反射实体类
        if(StringUtils.isEmpty(config.getClazz())) {
            throw new ServiceException(ErrorCode.PLAT_ERROR, "加载配置文件失败,全限定性类名为空");
        }

        Class clazz = null;
        try {
            clazz = Class.forName(config.getClazz());
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        }

        // 反向解析json格式数据为object对象
        Object o = JSON.parseObject(DataUtils.castStr(config.getConfig()), clazz);
        if(o == null) {
            try {
                o = clazz.newInstance();
            } catch (Exception e) {
                throw new ServiceException(ErrorCode.PLAT_ERROR, "获取配置文件异常");
            }
        }

        return o;
    }
}
